package asapIs134CK.womi.client.games.logoGame.froggitTheFrog;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import asapIs134CK.womi.client.games.GameOverHandler;
import asapIs134CK.womi.client.games.GameType;
import asapIs134CK.womi.client.games.GameWidget;
import asapIs134CK.womi.client.games.SuccessHandler;
import asapIs134CK.womi.client.imgs.logoGame.ActionImageBundle;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CellPanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

public class FroggitGameWigdet extends GameWidget{
	//core game elements
	private FroggitGame _frgGame;
	private List<GameOverHandler> _gameOverListener;
	//GUI elements
	private DockPanel _gameContainer;
	private Panel _actionsPanel;
	private RequestedActionWidget _requestedActions;
	private Panel _tipsPanel;
	private Panel _scorePanel;
	private Label _scoreInput;
	private Label _rightInput;
	private Label _missedInput;
	private DialogBox _winingBox;
	
	private static ActionImageBundle actionImgProvider = 
		(ActionImageBundle) GWT.create(ActionImageBundle.class);
	
	private class ScoreSubmitionHandler implements ClickHandler{
		
		private FroggitGameWigdet _game;
		
		public ScoreSubmitionHandler(FroggitGameWigdet game){
			_game = game;
		}
		
		@Override
		public void onClick(ClickEvent event) {
			int score = Integer.parseInt(_game._scoreInput.getText());
			_game.submitScore(score, GameType.FroggitTF);
		}
		
	}
	
	private class RequestedActionWidget extends Composite{
		//core game Element
		private FroggitGame _frgGame;
		//GUI elements
		private CellPanel _requestedAction;
		
		public RequestedActionWidget(FroggitGame frgG){
			_frgGame = frgG;
			_requestedAction = new HorizontalPanel();
			initRequestedAction();
			initWidget(_requestedAction);
		}
		private void initRequestedAction(){
			//don't really have something to Put here right now ...
		}
		public void validateAllActions(){
			_frgGame.validateAllActions();
			/*TODO for a nicer version of the game :
			 * delete action one by one as they are applied one the game
			 */
			emptyMe();
			//update the score :
			refreshScoringInput();
			
		}
		public void refreshScoringInput(){
			_scoreInput.setText(""+_frgGame.getScore());
			_rightInput.setText(""+_frgGame.getRight());
			_missedInput.setText(""+_frgGame.getMissed());
		}
		public void addNewAction(FroggitAction action){
			_frgGame.addNewAction(action);
			_requestedAction.add(action.getGUI());
		}
		public void removeLastAction() {
			_frgGame.removeLastAction();
			_requestedAction.remove(_requestedAction.getWidgetCount()-1);
		}
		public void removeAllActions() {
			_frgGame.removeAllActions();
			emptyMe();
		}
		private void emptyMe(){
			//System.out.println("emptyMe called");
			_requestedAction.clear();
		}
	}
	
	public FroggitGameWigdet() {
		super();
		_gameOverListener = new LinkedList<GameOverHandler>();
		_frgGame = new FroggitGame();
		
		_gameContainer = new DockPanel();
		_actionsPanel = new VerticalPanel();
		_requestedActions = new RequestedActionWidget(_frgGame);
		_tipsPanel = new VerticalPanel();
		_scorePanel = new VerticalPanel();
		_scoreInput = new Label("0");
		_rightInput = new Label("0");
		_missedInput = new Label("0");
		_winingBox = new DialogBox();
		initWidgetGUI();
		
		//now that we have create anything we need it's time to make the first update
		//_frgGame.updateImageGUI();
		
		//call initWidget to end the construction
		initWidget(_gameContainer);
	}

	public FroggitGameWigdet(FroggitWorld specificWorld) {
		super();
		_gameOverListener = new LinkedList<GameOverHandler>();
		_frgGame = new FroggitGame(specificWorld);
		
		_gameContainer = new DockPanel();
		_actionsPanel = new VerticalPanel();
		_requestedActions = new RequestedActionWidget(_frgGame);
		_tipsPanel = new VerticalPanel();
		_scorePanel = new VerticalPanel();
		_scoreInput = new Label("0");
		_rightInput = new Label("0");
		_missedInput = new Label("0");
		_winingBox = new DialogBox();
		initWidgetGUI();
		
		//now that we have create anything we need it's time to make the first update
		//_frgGame.updateImageGUI();
		
		//call initWidget to end the construction
		initWidget(_gameContainer);
	}
	
	private void initWidgetGUI() {
		//first the north with the banner
		Label frgBanner = new Label("Froggit the Frog ! " +
				"(put a real banner here ...)");
		frgBanner.setStylePrimaryName("froggitTF_banner");
		_gameContainer.add(frgBanner, DockPanel.NORTH);
		//then left and tips 
		initTips();
		Panel west = new VerticalPanel();
		west.add(_tipsPanel);
		initScore();
		west.add(_scorePanel);
		_gameContainer.add(west, DockPanel.WEST);
		//now right and action/validation
		initActionPanel();
		VerticalPanel east = new VerticalPanel();
		east.add(_actionsPanel);
		Button validate = new Button("Validate");
		validate.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				_requestedActions.validateAllActions();
			}
		});
		east.add(validate);
		_gameContainer.add(east, DockPanel.EAST);
		//same thing with the first south and social stuff
		Label socialStuff = new Label("here will be the social part of " +
				"Froggit the frog !");
		_gameContainer.add(socialStuff, DockPanel.SOUTH);
		//with the second south
		_requestedActions.setStylePrimaryName("froggitTF_requested");
		ScrollPanel makeActionsScroll = new ScrollPanel(_requestedActions);
		//TODO find a better way to do that than this ugly fix
		makeActionsScroll.setWidth("600px"); //<-- that's the ugly fix
		
		_gameContainer.add(makeActionsScroll, DockPanel.SOUTH);
		//and finally 
		Panel gamePanel = _frgGame.getGamePanel();
		gamePanel.setStylePrimaryName("froggitTF_board");
		_gameContainer.add(gamePanel, DockPanel.CENTER);
		
		
		
		_gameContainer.setSpacing(10);
		_gameContainer.setStylePrimaryName("froggitTF_main");
		
		
		
		//time to take care of the dialog box :
		_winingBox.setTitle("Congratulation you Win !");
		Panel winingPanel = new VerticalPanel();
		final Label congratulation = new Label(); 
		winingPanel.add(congratulation);
		Button submitScoreButton = new Button("Submit this score");
		submitScoreButton.addClickHandler(new ScoreSubmitionHandler(this));
		submitScoreButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				_winingBox.hide();
				notifyGameOver();
			}
		});
		Button skipThisGame = new Button("No way that score is too bad for me");
		skipThisGame.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				_winingBox.hide();
				notifyGameOver();
			}
		});
		HorizontalPanel submissionPanel = new HorizontalPanel();
		submissionPanel.add(submitScoreButton);
		submissionPanel.add(skipThisGame);
		
		winingPanel.add(submissionPanel);
		
		_winingBox.add(winingPanel);
		_frgGame.addSuccessHandler(new SuccessHandler() {
			
			@Override
			public void onSuccess(FroggitGame succeededGame) {
				//before print out the text refresh the score ...
				_requestedActions.refreshScoringInput();
				congratulation.setText("nice did ! you get "+
						_scoreInput.getText()+" points !");
				_winingBox.center();
			}
		});
	}

	private void initScore() {
		Label scoreLabel = new Label("Score :");
		Label rightLabel = new Label("Rights actions :");
		Label missedLabel = new Label("Wrong actions :");
		
		
		Panel scorePanel = new HorizontalPanel();
		scorePanel.add(scoreLabel);
		scorePanel.add(_scoreInput);
		
		Panel rightPanel = new HorizontalPanel();
		rightPanel.add(rightLabel);
		rightPanel.add(_rightInput);
		
		Panel missedPanel = new HorizontalPanel();
		missedPanel.add(missedLabel);
		missedPanel.add(_missedInput);
		
		_scorePanel.add(scorePanel);
		_scorePanel.add(rightPanel);
		_scorePanel.add(missedPanel);
	}

	private void initTips() {
		//TODO create more interaction for tips
		Label firstTips = new Label("try to guide Froggit to the Exit !");
		Label sndTips = new Label("More tips to come");
		Label trdTips = new Label("With more fancy interactions");
		
		_tipsPanel.add(firstTips);
		_tipsPanel.add(sndTips);
		_tipsPanel.add(trdTips);
		((CellPanel) _tipsPanel).setSpacing(5);
		_tipsPanel.setStylePrimaryName("froggitTF_tips");
		//roger we have finish here over!
	}
	
	private void initActionPanel() {
		//first create the different possible action
		Image imgUp = new Image(actionImgProvider.arrowUp());
		final Button Up = new Button("<img src=\""+imgUp.getUrl()+"\" alt=\"\" /> Up");
		Image imgDown = new Image(actionImgProvider.arrowDown());
		final Button Down = new Button("<img src=\""+imgDown.getUrl()+"\" alt=\"\" /> Down");
		Image imgLeft = new Image(actionImgProvider.arrowLeft());
		final Button Left = new Button("<img src=\""+imgLeft.getUrl()+"\" alt=\"\" /> Left");
		Image imgRight = new Image(actionImgProvider.arrowRight());
		final Button Right = new Button("<img src=\""+imgRight.getUrl()+"\" alt=\"\" /> Right");
		//then create the common handler
		class ActionButtonHandler implements ClickHandler{
			private FroggitAction _action;
			public ActionButtonHandler(FroggitAction act){
				_action = act;
			}
			@Override
			public void onClick(ClickEvent event) {
				//TODO create a sub widget who interact with the Game and use it here instead of dealing with both of GUI and core ...
				_requestedActions.addNewAction(_action);
			}
		}
		
		Up.addClickHandler(new ActionButtonHandler(FroggitAction.MoveToTop));
		Down.addClickHandler(new ActionButtonHandler(FroggitAction.MoveToDown));
		Left.addClickHandler(new ActionButtonHandler(FroggitAction.MoveToLeft));
		Right.addClickHandler(new ActionButtonHandler(FroggitAction.MoveToRight));
		
		//then add those button to the _actionsPanel
		_actionsPanel.add(Up);
		_actionsPanel.add(Down);
		_actionsPanel.add(Left);
		_actionsPanel.add(Right);
		
		//then add two button for editing action waiting list 
		final Button deleteAll = new Button("Delete all unapplied actions");
		final Button removeLast = new Button("Drop the last unapplied action");
		deleteAll.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				_requestedActions.removeAllActions();
			}
		});
		removeLast.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				_requestedActions.removeLastAction();
			}
		});
		_actionsPanel.add(deleteAll);
		_actionsPanel.add(removeLast);
		
		_actionsPanel.setStylePrimaryName("froggitTF_actions");
		((CellPanel) _actionsPanel).setSpacing(5);
		
	}

	
	
	@Override
	public void setVisible(boolean visible) {
		if(visible){
			_frgGame.updateImageGUI();
			//System.out.println("updateImgGUI done via setVisisble");
		}
		super.setVisible(visible);
	}
	
	public void refresh(){
		_frgGame.updateImageGUI();
	}
	
	public void addGameOverHandler(GameOverHandler handler){
		_gameOverListener.add(handler);
	}
	
	public void notifyGameOver(){
		Iterator<GameOverHandler> ite = _gameOverListener.iterator();
		while(ite.hasNext()){
			ite.next().onGameOver();
		}
	}
}
